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

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

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

Когда я делаю docker-compose up, я получаю следующее сообщение:

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".

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

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

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

Обновить

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

49
Albert Tobac 28 Фев 2016 в 10:40

2 ответа

Лучший ответ

Чтобы основываться на ответе Иракли, вот обновленное решение:

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

Docker-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 |                   | 

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

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

62
johntellsall 22 Мар 2017 в 19:21

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

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

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"

Который я тестировал и работал нормально. Подробнее о контейнерах только для данных можно узнать здесь: Чем хороши контейнеры данных Docker (объемы!)

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

  1. docker cp в контейнер только данных настройки или
  2. Используйте SQL-дамп данных вместо перемещения двоичных файлов (что я бы сделал).
11
Peter Mortensen 25 Июл 2018 в 05:08