Как использовать контейнер Postgresql с существующими данными?

Я пытаюсь настроить контейнер postgresql (https://hub.docker.com/_/postgres/). У меня есть данные из текущего экземпляра postgres. Я скопировал его из /var/lib/postgresql/data и хотите установить его как объем для контейнера postgres.

Моя часть из файла docker-compose.yml о postgres:

db:
    image: postgres:9.4
    ports:
        - 5432:5432
    environment:
        POSTGRES_PASSWORD: postgres
        POSTGRES_USER: postgres
        PGDATA : /var/lib/postgresql/data
    volumes:
        - /Users/ihorsamusenko/projects/own/docker_php/pgdata:/var/lib/postgresql/data

Когда я делаю сборку докеров, я получаю это сообщение:

db_1  | initdb: directory "/var/lib/postgresql/data" exists but is not empty
db_1  | If you want to create a new database system, either remove or empty
db_1  | the directory "/var/lib/postgresql/data" or run initdb
db_1  | with an argument other than "/var/lib/postgresql/data".

Я попытался создать свое собственное изображение из контейнера, поэтому мой файл Docker:

FROM postgres:9.4
COPY pgdata /var/lib/postgresql/data

Но у меня такая же ошибка, что я делаю неправильно?

Update

Я получил sql, используя pg_dumpall, и поместил его в /docker -entrypoint-initdb.d но этот файл выполняется каждый раз, когда я создаю докеры.

Я действительно новичок в докере, любые подсказки мне очень помогли.

Ответы

Ответ 1

Чтобы построить ответ irakli, здесь обновленное решение:

  • использовать новую версию 2 Docker Compose file
  • раздел volumes
  • удалены дополнительные настройки.

докер-compose.yml

version: '2'

services:
  postgres9:
    image: postgres:9.4
    expose:
      - 5432
    volumes:
      - data:/var/lib/postgresql/data

volumes:
  data: {}

демо

Запустите сервер базы данных Postgres:

$ docker-compose up

Показать все таблицы в базе данных. В другом терминале поговорите с контейнером Postgres:

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c '\z'

Он ничего не покажет, так как база данных пустая. Создать таблицу:

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c 'create table beer()'

Список вновь созданной таблицы:

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c '\z'

                         Access privileges
 Schema |   Name    | Type  | Access privileges | Column access privileges 
--------+-----------+-------+-------------------+--------------------------
 public | beer      | table |                   | 

Ура! Теперь мы запустили базу данных Postgres, используя общий том хранилища, и сохранили некоторые данные в нем. Следующим шагом является проверка того, что данные фактически склеиваются после остановки сервера.

Теперь уничтожьте контейнер сервера Postgres:

$ docker-compose stop

Запустите контейнер Postgres снова:

$ docker-compose up

Мы ожидаем, что сервер базы данных будет повторно использовать хранилище, поэтому наши очень важные данные все еще существуют. Проверьте:

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c '\z'
                         Access privileges
 Schema |   Name    | Type  | Access privileges | Column access privileges 
--------+-----------+-------+-------------------+--------------------------
public | beer      | table |                   | 

Мы успешно использовали файл Docker Compose нового стиля для запуска базы данных Postgres с использованием внешнего тома данных и проверили, что он сохраняет наши данные в безопасности и звуке.

сохранение данных

Сначала сделайте резервную копию, сохранив наши данные на хосте:

$ docker exec -it $(docker-compose ps -q postgres9 ) pg_dump -Upostgres > backup.sql

Замените наши данные из гостевой базы данных:

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c 'drop table beer'

Восстановите нашу резервную копию (хранящуюся на узле) в контейнере Postgres.

Примечание: используйте "exec -i", а не "-it", иначе вы получите сообщение "входное устройство не является TTY".

$ docker exec -i $(docker-compose ps -q postgres9 ) psql -Upostgres < backup.sql

Перечислите таблицы для проверки выполненного восстановления:

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c '\z'
                         Access privileges
Schema |   Name    | Type  | Access privileges | Column access privileges 
--------+-----------+-------+-------------------+--------------------------
public | beer      | table |                   | 

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

Спасибо Томаш!

Ответ 2

Похоже, у изображения Postgres возникают проблемы с смонтированными томами. FWIW, скорее всего, это проблема Postgres, чем Dockers, но это не имеет значения, потому что установка дисков не является рекомендуемым способом для хранения файлов базы данных. В любом случае.

Вместо этого вы должны создавать контейнеры-докеры только для данных. Вот так:

postgres9:
  image: postgres:9.4
  ports:
    - 5432:5432
  volumes_from:
    - pg_data
  environment:
    POSTGRES_PASSWORD: postgres
    POSTGRES_USER: postgres
    PGDATA : /var/lib/postgresql/data/pgdata

pg_data:
  image: alpine:latest
  volumes:
    - /var/lib/postgresql/data/pgdata
  command: "true"

который я тестировал и работал нормально. Вы можете больше узнать о контейнерах только для данных: https://medium.com/@ramangupta/why-docker-data-containers-are-good-589b3c6c749e

Что касается: как импортировать исходные данные, вы можете:

  • docker cp, в контейнер данных только для установки, или
  • используйте SQL-дамп данных вместо того, чтобы перемещать двоичные файлы (что я и делал).