Ошибка: импорт базы данных Postgres в контейнер докеров

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

Ниже приведено то, что я сделал до сих пор:

1) Добавлен bash script в папку /docker-entrypoint-initdb.d. script предназначен для создания базы данных:

psql -U docker -d postgres -c 'create database dbname;'

РЕЗУЛЬТАТ: Создана база данных, но сервер rails вышел с кодом 0. Ошибка: web_1 exited with code 0

2) Добавлен script для выполнения перед docker-compose up.

# Run docker db container
echo "Running db container"
docker-compose run -d db

# Sleep for 10 sec so that container have time to run
echo "Sleep for 10 sec"
sleep 10

echo 'Copying db_dump.gz to db container'
docker cp db_dump/db_dump.gz $(docker-compose ps -q db):/

# Create database `dbname`
echo 'Creating database `dbname`'
docker exec -i $(docker-compose ps -q db) psql -U docker -d postgres -c 'create database dbname;'

echo 'importing database `dbname`'
docker exec -i $(docker-compose ps -q db) bash -c "gunzip -c /db_dump.gz | psql -U postgres dbname"

РЕЗУЛЬТАТ: база данных создала и восстановила данные. Но другой контейнер запускается при запуске сервера веб-приложений с помощью docker-compose up.

docker--compose.yml:

version: '2'

services:

  db:
    image: postgres

    environment:
      - POSTGRES_PASSWORD=docker
      - POSTGRES_USER=docker

  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0' -d
    image: uname/application
    links:
      - db
    ports:
      - "3000:3000"
    depends_on:
      - db
    tty: true

Может кто-нибудь помочь создать и импортировать базу данных?

EDIT:

Я попробовал еще один подход, добавив переменную среды POSTGRES_DB=db_name в файл docker-compose.yml, чтобы создать базу данных и после запуска приложения (docker-compose up) я импортирую базу данных. Но получение ошибки: web_1 exited with code 0.

Я смущен, почему я получаю эту ошибку (в первом и третьем подходах), кажется, что что-то испортилось в файле docker-compose.

Ответ 1

Я получил его, добавив контейнер container_name для db. Мой контейнер db имеет другое имя (app_name_db_1), и я подключался к контейнеру с именем db.

После подачи жестко закодированного container_name (db) он будет работать.

Ответ 2

Настройка установки дампа базы данных

Вам нужно будет установить дамп в контейнер, чтобы вы могли получить к нему доступ. Что-то вроде этого в docker-compose.yml:

db:
  volumes:
    - './db_dump:/db_dump'

Создайте локальный каталог с именем db_dump и разместите там файл db_dump.gz.

Запустить контейнер базы данных

Используйте POSTGRES_DB в среде (как вы упомянули в своем вопросе) для автоматического создания базы данных. Начните db самостоятельно, без сервера rails.

docker-compose up -d db

Импортировать данные

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

docker-compose exec db gunzip /db_dump/db_dump.gz
docker-compose exec db psql -U postgres -d dbname -f /db_dump/db_dump.gz
docker-compose exec db rm -f /db_dump/db_dump.gz

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

Запустить сервер рельсов

docker-compose up -d web

Автоматизация этого

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

Ответ 3

web_1 exited with code 0

Вы пробовали проверить журнал контейнера web_1? docker-compose logs web

Я настоятельно рекомендую вам не инициализировать контейнер db вручную, сделать его автоматически в процессе запуска контейнера.

Посмотрите точку входа postgres, мы можем просто поместить каталог db_dump.gz в /docker-entrypoint-initdb.d/ контейнера, и он будет быть автоматическим исполнением, поэтому docker-compose.yml может быть:

db:
  volumes:
    - './initdb.d:/docker-entrypoint-initdb.d'

И поставьте db_dump.gz в ./initdb.d на локальном компьютере.

Ответ 4

Когда вы используете команду docker-compose run -d db

вы запускаете отдельный контейнер, это означает, что вы используете 3 контейнера, где 1 - приложение 2, - dbs. Контейнер, который вы запускаете с использованием вышеуказанной команды, не будет частью сервиса. compose использует отдельный db.

Итак, вместо запуска docker-compose up -d db запустите docker-compose up -d и продолжите свой script